package com.robusta.app.persistence;

import com.robusta.app.domain.spreadsheet.Model;
import com.robusta.app.model.spreadsheet.persistence.PersistableModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

import static com.google.common.base.Preconditions.checkState;

@Repository
public class SpreadsheetModelRepository implements InitializingBean {
    @PersistenceContext(unitName = "spreadsheet-model-persistence")
    private EntityManager entityManager;
    private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetModelRepository.class);

    protected SpreadsheetModelRepository() {

    }

    public PersistableModel find(Long id) {
        return entityManager.find(PersistableModel.class, id);
    }

    public void save(PersistableModel instance) {
        entityManager.persist(instance);
    }

    public void save(List<? extends Model> collection) {
        int persistedButNotFlushed = 0;
        for (Model entity : collection) {
            save((PersistableModel) entity); persistedButNotFlushed+= (entity.allFields().size() + 1); // 1 statement for each entity and 1 for each field entity.
            if (persistedButNotFlushed > 20 ) { //20, same as the JDBC batch size
                if(LOGGER.isDebugEnabled()) {
                    LOGGER.debug("20 Model objects added to persistence. Need to flush and clear entity manager.");
                }
                entityManager.flush();
                entityManager.clear();
                persistedButNotFlushed = 0;
                if(LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Flush and clear done. Adding additional model objects if any.");
                }
            }
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        checkState(entityManager != null);
        if(LOGGER.isDebugEnabled()) {
            LOGGER.debug(String.format("Obtained Entity Manager Instance: %s. Repository initialized", entityManager));
        }
    }
}
